import traceback

import numpy
import seaborn
import matplotlib.pyplot as plt
from manage.options import Search
from manage.options import Insert


class Draw:
    @staticmethod
    def histogram(x_ticks, data, x_label='课程', y_label='成绩', chart_name='我的成绩',
                  path=r'histogram.png'):
        """字体统一使用微软雅黑，传入五个参数，x_ticks(x轴显示内容，list)，data（数据，list），x、ylabel（xy轴的标签，str），
        chart_name（图表名称，str）,tick为"""
        plt.cla()
        plt.clf()
        try:
            plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
            plt.rcParams["axes.unicode_minus"] = False  # 该语句解决图像中的“-”负号的乱码问题
            # x = ['数据结构','普通物理','数学分析','微机原理','操作系统','数据库原理','编译原理','程序设计']
            # tick = [0, 1, 2, 3, 4, 5, 6, 7]
            tick = range(0, len(x_ticks))
            for a, b in zip(tick, data):
                plt.text(a, b + 0.05, '%.0f' % b, ha='center', va='bottom', fontsize=10)
            seaborn.barplot(x_ticks, data)
            seaborn.set_style('white', {'font.sans-serif': ['Microsoft YaHei', 'Arial']})
            seaborn.despine()
            plt.ylim([0, 100])
            plt.xlabel(x_label)
            plt.ylabel(y_label)
            plt.title(chart_name)
            plt.savefig(fname=f"{path}")
        except:
            print("未知错误")

    @staticmethod
    def line(x_ticks, data, data2, data3=[], chart_name='平均分变化', y_label='排名', x_label='学期',
             path=r'line.png', labels=['班级', '学院']):
        """字体统一使用微软雅黑，传入七个参数，x_ticks(x轴显示内容，list)，data（数据，list），data2,data3同理,x、ylabel（xy轴的标签，str），
            chart_name（图表名称，str）"""
        plt.cla()
        plt.clf()
        try:
            plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]  # 解决中文乱码问题
            plt.rcParams["axes.unicode_minus"] = False  # 该语句解决图像中的“-”负号的乱码问题
            seaborn.set_style('white', {'font.sans-serif': ['Microsoft YaHei', 'Arial']})

            for a, b in zip(x_ticks, data):
                plt.text(a, b, '%.1f' % b, ha='center', va='bottom', fontsize=8)
            if not len(data3) == 0:
                plt.text(x_ticks[0], data2[0], '%.1f' % data2[0], ha='center', va='bottom', fontsize=8)
                plt.text(x_ticks[-1], data3[0], '%.1f' % data3[0], ha='center', va='bottom', fontsize=8)
                seaborn.lineplot(x_ticks, data, label='我的')
                seaborn.lineplot(x_ticks, data2, label='班级')
                seaborn.lineplot(x_ticks, data3, label='学院')
                plt.legend(loc='lower right')
                plt.ylim([0, 100])
            else:
                for a, b in zip(x_ticks, data2):
                    plt.text(a, b, '%.1f' % b, ha='center', va='bottom', fontsize=8)
                seaborn.lineplot(x_ticks, data, label=labels[0])
                seaborn.lineplot(x_ticks, data2, label=labels[1])
                plt.legend(loc='upper right')
            seaborn.despine()
            plt.xlabel(x_label)
            plt.ylabel(y_label)
            plt.title(chart_name)
            plt.savefig(fname=f"{path}")
            # plt.show()
        except Exception:
            # print("未知错误")
            traceback.print_exc()

    @staticmethod
    def pie(x_ticks, label, chart_name, path=r'pie.png'):
        plt.cla()
        plt.clf()
        try:
            plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
            plt.rcParams["axes.unicode_minus"] = False  # 该语句解决图像中的“-”负号的乱码问题
            plt.pie(x_ticks, labels=label, autopct='%1.1f%%', startangle=90, counterclock=False);
            seaborn.set_style('white', {'font.sans-serif': ['Microsoft YaHei', 'Arial']})
            plt.title(chart_name)
            plt.savefig(fname=f"{path}")
            # plt.show()
        except:
            print("未知错误")


class Avg:
    @staticmethod
    def my(table_name, target_num):
        """输入table_name（str）用于查询score表（区分哪一年），target_num（str）用于输入学号"""
        try:
            if not table_name.startswith('score'):
                print("错误输入")
                return 0
            else:
                pre_res = Search.row(f'{table_name}', f'{target_num}')
                result = []
                for i in pre_res:
                    result.append(i[1])
                ans = numpy.mean(result)
                return round(ans, 2)
        except:
            return 0

    @staticmethod
    def classes(table_name, sclass):
        """输入table_name（str）用于查询score表（区分哪一年），sclass（int）用于输入班级号"""
        try:
            if not table_name.startswith('score'):
                print("错误输入")
                return 0
            else:
                pre_res = Search.by_class(f'{table_name}', f'{sclass}')
                result = []
                for i in pre_res:
                    result.append(i[2])
                ans = numpy.mean(result)
                return round(ans, 2)
        except:
            return 0

    @staticmethod
    def dept(table_name, dept):
        """输入table_name（str）用于查询score表（区分哪一年），sclass（str）用于输入学院名称"""
        try:
            if not table_name.startswith('score'):
                print("错误输入")
                return 0
            else:
                pre_res = Search.by_dept(f'{table_name}', f'{dept}')
                result = []
                for i in pre_res:
                    result.append(i[2])
                ans = numpy.mean(result)
                return round(ans, 2)
        except:
            return 0

    @staticmethod
    def persentage(table_name, target, target_num):
        """输入table_name（str）用于查询score表（区分哪一年），course（int）用于输入课程号"""
        try:
            if not table_name.startswith('score'):
                print("错误输入")
                return 0
            else:
                if target == 'course':
                    pre_res = Search.by_course(f'{table_name}', f'{target_num}')
                elif target == 'dept':
                    pre_res = Search.by_dept(f'{table_name}', f'{target_num}')
                else:
                    print("错误输入")
                    return 0
                result = [0, 0, 0, 0, 0]
                for i in pre_res:
                    b = int((i[2] // 10) - 6)
                    if b < 0:
                        b = -1
                    if b == 4:
                        b = 3
                    b += 1
                    result[b] += 1
                return result
        except:
            print("未知错误")
            return 0

    @staticmethod
    def percentage_list(data):
        # try:
        result = [0, 0, 0, 0, 0]
        for i in data:
            tmp = int((i // 10) - 6)
            if tmp < 0:
                tmp = -1
            if tmp == 4:
                tmp = 3
            tmp += 1
            result[tmp] += 1
        return result

    # except:
    #     print("未知错误")
    #     return 0

    @staticmethod
    def ranking(target, table_name, value, my_score, year=1):
        """输入table_name（str）用于区分班级还是学院排名，应该输入class_avg或者dept_avg，value是区分值（主键），
        my_score（float）用于输入我的成绩以查询排名，year（int）用于区分年份"""
        try:
            result = []
            if target == 'classes':
                pre_res = Search.by_class(f'{table_name}', value)
            elif target == 'dept':
                pre_res = Search.by_dept(f'{table_name}', f'{value}')
            else:
                print("错误输入")
                return 0
            for i in pre_res:
                result.append(i[year])
            result.sort(reverse=True)
            return result.index(my_score) + 1
        except ValueError:
            print("你输入的成绩不存在")

    @staticmethod
    def import_classavg(target_list, year):
        for i in target_list:
            if year == 1:
                a = Avg.classes('score1', i)
                Insert.ins_avg('class_avg', i, a)
            elif year == 2:
                a = Avg.classes('score1', i)
                b = Avg.classes('score2', i)
                Insert.ins_avg('class_avg', i, a, b)
            elif year == 3:
                a = Avg.classes('score1', i)
                b = Avg.classes('score2', i)
                c = Avg.classes('score3', i)
                Insert.ins_avg('class_avg', i, a, b, c)
            elif year == 4:
                a = Avg.classes('score1', i)
                b = Avg.classes('score2', i)
                c = Avg.classes('score3', i)
                d = Avg.classes('score4', i)
                Insert.ins_avg('class_avg', i, a, b, c, d)

    @staticmethod
    def import_deptavg(target_list, year):
        for i in target_list:
            if year == 1:
                a = Avg.dept('score1', i)
                Insert.ins_avg('dept_avg', i, a)
            elif year == 2:
                a = Avg.dept('score1', i)
                b = Avg.dept('score2', i)
                Insert.ins_avg('dept__avg', i, a, b)
            elif year == 3:
                a = Avg.dept('score1', i)
                b = Avg.dept('score2', i)
                c = Avg.dept('score3', i)
                Insert.ins_avg('dept_avg', i, a, b, c)
            elif year == 4:
                a = Avg.dept('score1', i)
                b = Avg.dept('score2', i)
                c = Avg.dept('score3', i)
                d = Avg.dept('score4', i)
                Insert.ins_avg('dept_avg', i, a, b, c, d)

    @staticmethod
    def import_myavg(target_list, year):
        for i in target_list:
            if year == 1:
                a = Avg.my('score1', f'{i}')
                Insert.ins_avg('my_avg', f'{i}', a)
            elif year == 2:
                a = Avg.my('score1', f'{i}')
                b = Avg.my('score2', f'{i}')
                Insert.ins_avg('my_avg', f'{i}', a, b)
            elif year == 3:
                a = Avg.my('score1', f'{i}')
                b = Avg.my('score2', f'{i}')
                c = Avg.my('score3', f'{i}')
                Insert.ins_avg('my_avg', f'{i}', a, b, c)
            elif year == 4:
                a = Avg.my('score1', f'{i}')
                b = Avg.my('score2', f'{i}')
                c = Avg.my('score3', f'{i}')
                d = Avg.my('score4', f'{i}')
                Insert.ins_avg('my_avg', f'{i}', a, b, c, d)